package net.homelinux.chaoswg.io.renga.krypto.animations.Split8;

import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

import net.homelinux.chaoswg.io.higherorderfunctions.UnaryFunction;
import net.homelinux.chaoswg.io.renga.core.helper.datatypes.Octet;
import net.homelinux.chaoswg.io.renga.core.registries.GlobalPropertyRegistry;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.numerical.UnsignedNBit;
import net.homelinux.chaoswg.io.renga.krypto.operations.type.Split8;

public class Split8StateChanger implements Runnable {
    final UnaryFunction<Octet<UnsignedNBit, UnsignedNBit,UnsignedNBit, UnsignedNBit,UnsignedNBit, UnsignedNBit,UnsignedNBit, UnsignedNBit>, UnsignedNBit> split8 = new Split8 ();
    final Split8State initialState;
    JLabel jlIn = null;
    JLabel jlout1 = null;
    JLabel jlout2 = null;
    JLabel jlout3 = null;
    JLabel jlout4 = null;
    JLabel jlout5 = null;
    JLabel jlout6 = null;
    JLabel jlout7 = null;
    JLabel jlout8 = null;
    JFrame jw;

    public Split8StateChanger(Split8State initialState) {
        this.initialState = initialState;

        jw = new JFrame ("Split-8");
        jw.getContentPane().add(getPanel());
        jw.setLocationRelativeTo(null);
        
        jw.setSize(500, 100);
    }

    public JPanel getPanel() {
        final JPanel toReturn = new JPanel (new GridLayout(2,1));
        final JPanel south = new JPanel (new GridLayout(1,4));
        south.add (jlout1 = new JLabel (initialState.getOut().getFirst().toString()));
        south.add (jlout2 = new JLabel (initialState.getOut().getSecond().toString()));
        south.add (jlout3 = new JLabel (initialState.getOut().getFirst().toString()));
        south.add (jlout4 = new JLabel (initialState.getOut().getSecond().toString()));
        south.add (jlout5 = new JLabel (initialState.getOut().getFirst().toString()));
        south.add (jlout6 = new JLabel (initialState.getOut().getSecond().toString()));
        south.add (jlout7 = new JLabel (initialState.getOut().getFirst().toString()));
        south.add (jlout8 = new JLabel (initialState.getOut().getSecond().toString()));


        toReturn.add(jlIn = new JLabel (initialState.getIn().toString()));

        toReturn.add(south);
        toReturn.setBorder(new BevelBorder (BevelBorder.RAISED));

        jlIn.setHorizontalAlignment(JLabel.CENTER);
        jlout1.setHorizontalAlignment(JLabel.CENTER);
        jlout2.setHorizontalAlignment(JLabel.CENTER);
        jlout3.setHorizontalAlignment(JLabel.CENTER);
        jlout4.setHorizontalAlignment(JLabel.CENTER);
        jlout5.setHorizontalAlignment(JLabel.CENTER);
        jlout6.setHorizontalAlignment(JLabel.CENTER);
        jlout7.setHorizontalAlignment(JLabel.CENTER);
        jlout8.setHorizontalAlignment(JLabel.CENTER);

        return toReturn;
    }
    
    private void setNew () {
        jlIn.setText(initialState.getIn().toHexString());
        jlIn.paintImmediately(jlIn.getVisibleRect());
        jlout1.setText(initialState.getOut().getFirst().toHexString());
        jlout1.paintImmediately(jlout1.getVisibleRect());
        jlout2.setText(initialState.getOut().getSecond().toHexString());
        jlout2.paintImmediately(jlout2.getVisibleRect());
        jlout3.setText(initialState.getOut().getThird().toHexString());
        jlout3.paintImmediately(jlout3.getVisibleRect());
        jlout4.setText(initialState.getOut().getForth().toHexString());
        jlout4.paintImmediately(jlout4.getVisibleRect());
        jlout5.setText(initialState.getOut().getFifth().toHexString());
        jlout5.paintImmediately(jlout5.getVisibleRect());
        jlout6.setText(initialState.getOut().getSixth().toHexString());
        jlout6.paintImmediately(jlout6.getVisibleRect());
        jlout7.setText(initialState.getOut().getSeventh().toHexString());
        jlout7.paintImmediately(jlout7.getVisibleRect());
        jlout8.setText(initialState.getOut().getEighth().toHexString());
        jlout8.paintImmediately(jlout8.getVisibleRect());
    }

    public void run() {
        int delay = ((Integer)GlobalPropertyRegistry.getGlobalPropertyRegistry().getProperty("animationSpeed")) * 100;
        
        jw.setVisible(true);

        UnsignedNBit input = initialState.getIn();
        Octet<UnsignedNBit, UnsignedNBit,UnsignedNBit, UnsignedNBit,UnsignedNBit, UnsignedNBit,UnsignedNBit, UnsignedNBit> out = split8.apply(input);
        setNew();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}

        initialState.setOut(out);
        setNew();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
        /*
        initialState.getOut().setFirst(out.getFirst());
        setNew ();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}

        initialState.getOut().setSecond(out.getSecond());
        setNew ();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}

        initialState.getOut().setThird(out.getThird());
        setNew ();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}

        initialState.getOut().setForth(out.getForth());
        setNew ();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}

        initialState.getOut().setFifth(out.getFifth());
        setNew ();
        
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
        initialState.getOut().setSixth(out.getSixth());
        setNew ();

        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
        initialState.getOut().setSeventh(out.getSeventh());
        setNew ();
        
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
        initialState.getOut().setEighth(out.getEighth());
        setNew ();
        
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
        */
}
    
    public void close () {
        jw.dispose();
    }
}
